package com.sunmouse.toolkit.fragment.home;


import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Bundle;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SeekBar;
import android.widget.TextView;

import com.sunmouse.toollib.adapter.BasicRecyclerAdapter;
import com.sunmouse.toollib.receiver.OnReceiveListener;
import com.sunmouse.toollib.utils.DialogUtil;
import com.sunmouse.toollib.utils.FileUtils;
import com.sunmouse.toollib.utils.JumpUtils;
import com.sunmouse.toollib.utils.LogUtils;
import com.sunmouse.toollib.utils.StringUtils;
import com.sunmouse.toollib.utils.TipsUtils;
import com.sunmouse.toollib.utils.ToastUtils;
import com.sunmouse.toollib.utils.system.PermissionUtil;
import com.sunmouse.toollib.utils.system.SystemUtils;
import com.sunmouse.toolkit.R;
import com.sunmouse.toolkit.activity.ContentActivity;
import com.sunmouse.toolkit.adapter.FunAdapter;
import com.sunmouse.toolkit.bean.PageBean;
import com.sunmouse.toolkit.receiver.ProgressReceiver;
import com.sunmouse.toolkit.constant.Config;
import com.sunmouse.toolkit.constant.Value;
import com.sunmouse.toolkit.fragment.BaseFragment;
import com.sunmouse.toolkit.service.AudioService;
import com.sunmouse.toolkit.util.PageUtil;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * A simple {@link Fragment} subclass.
 */
public class MediaFragment extends BaseFragment implements OnReceiveListener {
    //    public static final String RECORD_FILE = FileUtils.getStoragePath() + "/Innocence.mp3";
    public static final String RECORD_FILE = FileUtils.getStoragePath() + "/voice.wav";
    public static final String ENCODE_FILE = FileUtils.getStoragePath() + "/encode.wav";
    public static final int REQUEST_CODE = 5;

    @BindView(R.id.m_list)
    RecyclerView mList;
    Unbinder unbinder;


    private MediaRecorder mRecorder;
    private ProgressReceiver mReceiver;
    private boolean isPlaying = false;
    private boolean isRecording = false;
    private Timer mTimer;
    private int count;

    private TipsUtils mTips;
    private DialogUtil mDialogUtil;
    private TextView timeTv;
    private TextView startTv;
    private TextView overTv;

    public MediaFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_media, container, false);
        unbinder = ButterKnife.bind(this, view);
        return view;
    }


    @Override
    public void init() {
        super.init();
        this.mData = new ArrayList<>();
        this.mAdapter = new FunAdapter(mData, getActivity());
        this.mList.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
        this.mList.setAdapter(mAdapter);
        mAdapter.setOnItemClickListener(new ItemClick());
        loadingData(1);


        mReceiver = new ProgressReceiver();
        getActivity().registerReceiver(mReceiver, new IntentFilter(Value.Action.AUDIO_PROGRESS));
        mReceiver.setOnReceiveListener(this);
//        mSeek.setOnSeekBarChangeListener(new SeekBarChangedHandle());

        initDialog();

        //request permission
        String[] recordPermission = {
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.RECORD_AUDIO

        };
        if (!PermissionUtil.isPermitted(getActivity(), recordPermission)) {
            PermissionUtil.requestPermission(getActivity(), recordPermission, REQUEST_CODE);
            return;
        }
        initRecorder();
    }

    @Override
    public void initDialog() {
        //record dialog
        View v = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_recorder, null);
        timeTv = (TextView) v.findViewById(R.id.time_tv);
        startTv = (TextView) v.findViewById(R.id.start_tv);
        overTv = (TextView) v.findViewById(R.id.over_tv);
        this.startTv.setOnClickListener(this);
        this.overTv.setOnClickListener(this);
        DisplayMetrics metrics = getResources().getDisplayMetrics();
        this.mDialogUtil = DialogUtil.init()
                .view(v)
                .width((int) (metrics.widthPixels * 0.8))
                .height((int) (metrics.heightPixels * 0.4))
                .build(getActivity());

        mTips = TipsUtils.getInstance(getActivity());
        mTips.setCancelTxt("start");
        mTips.setConfirmTxt("end");
        mTips.setOnCancelClickListener(this);
        mTips.setOnConfirmClickListener(this);
    }

    /**
     * check media info
     */
    private void checkMediaInfo() {
        File f = FileUtils.newFile(RECORD_FILE);

        MediaFormat mf;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            MediaExtractor mediaExtractor = new MediaExtractor();
            try {
                mediaExtractor.setDataSource(f.getAbsolutePath());
                int numTracks = mediaExtractor.getTrackCount();
                for (int i = 0; i < numTracks; i++) {
                    mf = mediaExtractor.getTrackFormat(i);
                    LogUtils.v("--------------:" + mf.getString(MediaFormat.KEY_MIME));
                }
                LogUtils.v("--------------time=" + mediaExtractor.getSampleTime());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    @Override
    public void loadingData(int page) {
        this.mData.add(new PageBean(PageUtil.Index.RECORDER, "record"));
        this.mData.add(new PageBean(PageUtil.Index.PLAYER, "player"));
        this.mData.add(new PageBean(PageUtil.Index.ENCODER, "encoder"));

        mAdapter.notifyDataSetChanged();
    }


    @Override
    public void onClick(View v) {
        super.onClick(v);
        if (v == startTv) {
            startRecording();
            return;
        }
        if (v == overTv) {
            overRecording();
            return;
        }


    }


    /**
     * play media
     */
    private void playMedia() {
        if (!SystemUtils.isServiceWork(getActivity(), AudioService.class.getSimpleName())) {
            mIntent = new Intent(getActivity(), AudioService.class);
            mIntent.setAction(Value.Action.AUDIO);
            mIntent.putExtra(Config.Key.MEDIA, RECORD_FILE);
            getActivity().startService(mIntent);
            return;
        }

        sendCommand(isPlaying ? Value.Control.PAUSE : Value.Control.PLAY);
    }

    /**
     * send command
     *
     * @param command
     */
    private void sendCommand(int command) {
        mIntent = new Intent().setAction(Value.Action.AUDIO_COMMAND);
        mIntent.putExtra(Config.Key.CONTROL, command);
        getActivity().sendBroadcast(mIntent);
    }


    /**
     * stop recording
     */
    private void overRecording() {
        if (mRecorder == null) {
            ToastUtils.simpleToast(getActivity(), "please start recording first");
            return;
        }
        mRecorder.stop();
        mRecorder.release();
        mRecorder = null;
        ToastUtils.simpleToast(getActivity(), "---stop  recording");
    }

    /**
     * start record
     */
    private void startRecording() {
        if (!isRecording) {
            try {
                mRecorder.prepare();
                mRecorder.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return;
        }
    }

    /**
     * init recorder
     */
    private synchronized void initRecorder() {
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//set audio source
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setOutputFile(RECORD_FILE);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mRecorder.setOnInfoListener(new RecordInfoHandle());

        mTimer = new Timer();
        mTimer.schedule(new RecordTimeTask(), 0, 1000);

    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (grantResults.length < 1) {
            ToastUtils.simpleToast(getActivity(), "permission request unsuccessfully");
            return;
        }

        //record permission
        if (requestCode == REQUEST_CODE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                initRecorder();
            }
        }
    }

    @Override
    public void onPause() {
        super.onPause();

        if (mRecorder != null) {
            mRecorder.release();
            mRecorder = null;
        }

    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();

        if (mTimer != null) {
            mTimer.cancel();
            mTimer = null;
        }
        if (mDialogUtil.isShowing())
            mDialogUtil.dismiss();

        getActivity().unregisterReceiver(mReceiver);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent == null || !intent.getAction().equals(Value.Action.AUDIO_PROGRESS)) return;
        //progress bar
        int duration = intent.getIntExtra(Config.Key.DURATION, -1);
        int progress = intent.getIntExtra(Config.Key.PROGRESS, -1);
        LogUtils.v("-----------------" + progress);
        if (duration != -1) {
//            durationTv.setText(StringUtils.parseTime(duration));
        }

        if (progress != -1) {
//            cursorTv.setText(StringUtils.parseTime(progress));

//            mSeek.setProgress(progress * 100 / duration);

        }
        /*
        playing status
         */
        int status = intent.getIntExtra(Config.Key.STATUS, -1);
        if (status == -1) return;

        switch (status) {
            case Value.Status.PLAYING:
                ToastUtils.simpleToast(getActivity(), "----start playing----");
                isPlaying = true;
                break;
            default:
                isPlaying = false;
                ToastUtils.simpleToast(getActivity(), "----stop playing----");
                break;

        }
    }


    @Override
    public void onHandleMessage(Message msg) {
        super.onHandleMessage(msg);
        switch (msg.what) {
            case Value.RECORD:
                mTips.setDesc(StringUtils.parseTime(msg.arg1 * 1000));
                break;
        }
    }

    /**
     * seek bar changed  handle
     */
    class SeekBarChangedHandle implements SeekBar.OnSeekBarChangeListener {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            LogUtils.d("--------onProgressChanged-----------");
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            LogUtils.d("--------onStartTrackingTouch-----------");

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            LogUtils.d("--------onStopTrackingTouch-----------");
            mIntent = new Intent().setAction(Value.Action.AUDIO_COMMAND);
            mIntent.putExtra(Config.Key.CONTROL, Value.Control.NEW_PROGRESS);
            mIntent.putExtra(Config.Key.PROGRESS, seekBar.getProgress());
            getActivity().sendBroadcast(mIntent);
        }
    }


    /**
     * record info handle
     */
    private class RecordInfoHandle implements MediaRecorder.OnInfoListener {
        @Override
        public void onInfo(MediaRecorder mr, int what, int extra) {

        }
    }

    /**
     * record error listener
     */
    private class RecordErrorHandle implements MediaRecorder.OnErrorListener {
        @Override
        public void onError(MediaRecorder mr, int what, int extra) {

        }
    }

    /**
     * record time task
     */
    class RecordTimeTask extends TimerTask {
        @Override
        public void run() {
            if (mRecorder == null || !isRecording) return;
            mMsg = Message.obtain();
            mMsg.what = Value.RECORD;
            mMsg.arg1 = count++;
            mHandler.sendMessage(mMsg);
        }
    }

    /**
     * item click
     */
    class ItemClick implements BasicRecyclerAdapter.OnItemClickListener {
        @Override
        public void onItemClick(int position) {
            int index = mData.get(position).getId();

            if (index == PageUtil.Index.RECORDER) {
                //show record dialog
                mDialogUtil.show();
                return;
            }
            if (index == PageUtil.Index.PLAYER) {
                //show player dialog
                return;
            }
            if (index == PageUtil.Index.ENCODER) {
                //show encoder dialog
                Bundle mBundle = new Bundle();
                mBundle.putString(Config.Key.MEDIA, RECORD_FILE);
                mBundle.putInt(Config.Key.INDEX, PageUtil.Index.MEDIA_EDIT);
                JumpUtils.jumpWithParams(getActivity(), ContentActivity.class, mBundle);
                return;
            }
        }
    }
}
